package domainLogic;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;


public class ItemView extends Item {
	int highest_price;
	String highest_bidder;
	int numbids;
	String category_name;
	
	private final static double MINIMUM_BID_PRICE_PERCENT = 1.05;
	
	public int getHighestPrice() {
		return highest_price;
	}
	public void setHighestPrice(int highest_price) {
		this.highest_price = highest_price;
	}
	public String getHighestBidder() {
		return highest_bidder;
	}
	public void setHighestBidder(String highest_bidder) {
		this.highest_bidder = highest_bidder;
	}
	public int getNumBids() {
		return numbids;
	}
	public void setNumBids(int numbids) {
		this.numbids = numbids;
	}
	public String getCategoryName() {
		return category_name;
	}
	public void setCategoryName(String category_name) {
		this.category_name = category_name;
	}
	
	public static String convertTime(long aTimeSec)
	{
		final long MIN_SEC = 60;
		final long HOUR_SEC = MIN_SEC * 60;
		final long DAY_SEC = HOUR_SEC * 24;
		
		String ret="";
		long time = aTimeSec;
		
		if(time > DAY_SEC)
		{
			ret += (time/DAY_SEC) + "d ";
			time -= (time/DAY_SEC)*DAY_SEC;
		}
		if(time > HOUR_SEC)
		{
			ret += (time/HOUR_SEC) + "h ";
			time -= (time/HOUR_SEC)*HOUR_SEC;
		}
		if(time > MIN_SEC)
		{
			ret += (time/MIN_SEC) + "m ";
			time -= (time/MIN_SEC)*MIN_SEC;
		}
		if(ret.equals(""))
			ret += time + "s ";

		return ret;
	}
	
	public String getRemainingTime()
	{
		long remainingMilli = getRealenddate().getTime() - java.util.Calendar.getInstance().getTimeInMillis();
		if(remainingMilli <= 0)
			return "Bid is over";
		
		return convertTime(remainingMilli/1000);
	}
	public int getPrice()
	{
		int price = Math.max(getStartingprice(), getHighestPrice());
		
		return price;
	}
	public String getWinner()
	{
		if(!isBidClosed())
			return "Not completed";
		if(getNumBids() == 0)
			return "No Bids";
		if(!isReservedpriceReached())
			return "No Winner";
		return getHighestBidder();
	}
	public boolean isEnddatePassed()
	{
		return getRealenddate().before( java.util.Calendar.getInstance().getTime());
	}
	public boolean isBidClosed()
	{
		if(isEnddatePassed())
			return true;

		if(getEndnotified() == 'Y')
			return true;
		
		if(getBuyoutprice() >0 && getHighestPrice() >= getBuyoutprice() && getNumBids() != 0)
			return true;
		
		return false;
	}
	public boolean isReservedpriceReached()
	{
		if(getReserveprice() == 0)
			return true;
		
		if(getHighestPrice() >= getReserveprice())
			return true;
		
		return false;
	}
	public int nextBidPrice()
	{
		int minPrice = 0;
		if(this.getNumBids() == 0 )
			minPrice = this.getStartingprice();
		else
			minPrice = (int) Math.ceil(this.getHighestPrice()*MINIMUM_BID_PRICE_PERCENT);
		
		if(minPrice == 0)
			minPrice = 1;
		
		return minPrice;
	}
	
	public boolean validateBid(Bid newBid, javax.servlet.jsp.JspWriter out) throws IOException
	{
		int minPrice = this.nextBidPrice();
		
		System.out.println("validateBid : minprice = " + minPrice + ", new price =" + newBid.getPrice());
		
		// Check minimum price that can be bidded.
		if(minPrice > newBid.getPrice())
		{
			out.println(common.JspUtil.makeErrorMsg( "Someone already bidded. Please input more than "+minPrice,
					common.JspUtil.URL_CONTENT_PAGE+"/items/viewItemDetail.jsp?itemId="+newBid.getItemId() ) );
			return false;
		}
		
		// Check whether the bid is closed or not
		if(this.isEnddatePassed())
		{
			out.println(common.JspUtil.makeErrorMsg("Bid is closed already.", common.JspUtil.URL_DEFAULT));
			return false;
		}
		
		return true;
	}
	
	public synchronized void updateEndDate(Bid newBid)
	{
		// If bid is closing within 1 minute, extend it for 10 mins
		if(this.getRealenddate().getTime() - java.util.Calendar.getInstance().getTimeInMillis() <= 1*60*1000)	//1 mins * 60 sec * 1000 ms
		{
			System.out.println("createNewBid : Bid is almost done. Extend real end date by 10 mins!");
			extendRealenddate();
		}
	
		// If bid price is reached to buyout price, close the bid
		if(newBid.getPrice() >= this.getBuyoutprice() && this.getBuyoutprice() > 0)
		{
			System.out.println("createNewBid : Price reached buyout price. Set realenddate to current !");
			closeBid();
		}
	}
	
	private void extendRealenddate()
	{
		Timestamp newTimestamp = new Timestamp(java.util.Calendar.getInstance().getTimeInMillis() + 10*60*1000);
		dataGateway.ItemTable.getInstance().updateItemRealenddate(this.getId(), newTimestamp);	
	}

	private void closeBid()
	{
		Timestamp now = new Timestamp(java.util.Calendar.getInstance().getTimeInMillis());
		dataGateway.ItemTable.getInstance().updateItemRealenddate(this.getId(), now);	
	}

	public ItemView(ResultSet rs) {
		super(rs);
		
		try {
			setHighestPrice(rs.getInt("highest_price"));
			setHighestBidder(rs.getString("highest_bidder"));
			setNumBids(rs.getInt("numbids"));
			setCategoryName(rs.getString("cateogory_name"));
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
